package cn.leedsoft.luma.test.design_pattern;

/**
 * 工厂方法模式
 * Created by leeds on 2017/6/14.
 * 工厂方法的作用：
 * 1、控制反转：将new对象的任务交给工厂。。根据参数的变化，产生不同的产品。
 * 2、依赖注入。
 * <p>
 * 实现细节：
 * 1、产品接口、具体产品。
 * 2、工厂接口、具体工厂
 * 3、工厂接口提供工厂方法：接收具体产品的class参数、其他参数，对产品进行装配，返回具体产品
 *
 *
 * 简单工厂模式，又叫静态工厂模式。
 * 1、【产品接口、】具体产品。
 * 2、具体工厂，提供静态工厂方法：接收具体产品的class参数、其他参数，对产品进行装配，返回具体产品
 */
public class FactoryMethod {
    public static void main(String[] args) {
        Factory cFactory = new NumberOneFactory();
        FoodProduct food = cFactory.createProduct(FoodProduct.class);
        food.mothod1();
        food.mothod2();
    }
}

//产品接口
abstract class Product {
    public void mothod1() {
        System.out.println("方法一，加工的都是使用的产品...");
    }

    public abstract void mothod2();
}

//具体产品
class FruitProduct extends Product {
    @Override
    public void mothod2() {
        System.out.println("方法二，生产出来了果汁....");
    }
}
class FoodProduct extends Product {
    //    public FoodProduct(){
    //        super();
    //    }
    ////通过反射获取Constructor进行实例化时注意：此时无法调用系统默认加上的构造器。如想调用，必须显式声明。
    public static void main(String[] args) throws Exception {
//        FoodProduct.class.newInstance();
        FoodProduct.class.getConstructor().newInstance();
    }

    @Override
    public void mothod2() {
        System.out.println("方法二，生产出来了零食....");
    }
}

//工厂接口
abstract class Factory {
    public abstract <T extends Product> T createProduct(Class<T> t);
}
//具体工厂
class NumberOneFactory extends Factory {
    @Override
    public <T extends Product> T createProduct(Class<T> t) {
        Product p = null;
        try {
            p = t.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) p;
    }
}